// src/components/MapComponent.tsx
import React, { useRef, useEffect, useCallback } from "react";
import L from "leaflet";
import "leaflet/dist/leaflet.css";
import type { Feature, Polygon, LineString, Point } from "geojson"; // 导入 GeoJSON 类型
import type { DebugData, MissionType } from "../App"; // 导入 DebugData 接口
import { AIRPORT_COORDS } from "./utils"; // 新增：导入 AIRPORT_COORDS

interface MapComponentProps {
  drawnPolygon: L.Polygon | null;
  setDrawnPolygon: (polygon: L.Polygon | null) => void;
  onPolygonCreated: (layer: L.Polygon) => void;
  onPolygonEdited: (layer: L.Polygon) => void;
  onPolygonDeleted: () => void;
  flightPathLayer: L.FeatureGroup | null;
  setFlightPathLayer: (layer: L.FeatureGroup | null) => void;
  isDrawingEnabled: boolean;
  debugData: DebugData | null; // <-- debug prop
  showDebugLayers: boolean; // 控制debug prop
  // 起飞点相关 props
  takeoffPoint: L.LatLng;
  setTakeoffPoint: (latlng: L.LatLng) => void;
  isSettingTakeoffPoint: boolean;
  onSetTakeoffPointMode: (enabled: boolean) => void;
}

const MapComponent: React.FC<MapComponentProps> = ({
  drawnPolygon,
  setDrawnPolygon,
  onPolygonCreated,
  onPolygonEdited,
  onPolygonDeleted,
  flightPathLayer,
  setFlightPathLayer,
  isDrawingEnabled,
  debugData, // <-- 解构 prop
  showDebugLayers, // 解构新 prop
  takeoffPoint,
  setTakeoffPoint,
  isSettingTakeoffPoint,
  onSetTakeoffPointMode,
}) => {
  const mapRef = useRef<L.Map | null>(null);
  const drawnItemsRef = useRef<L.FeatureGroup | null>(null);
  const drawingPointsRef = useRef<L.LatLng[]>([]);
  const tempPolygonRef = useRef<L.Polygon | null>(null);
  const clickTimeoutRef = useRef<number | null>(null);
  const debugLayersRef = useRef<L.FeatureGroup | null>(null); // <-- 新增调试图层组

  // 存储底图图层实例的引用
  const osmLayerRef = useRef<L.TileLayer | null>(null);
  const esriSatelliteLayerRef = useRef<L.TileLayer | null>(null);
  const googleSatelliteLayerRef = useRef<L.TileLayer | null>(null);
  const activeBaseLayerRef = useRef<L.TileLayer | null>(null); // 存储当前激活的底图

  // 存储图层控制器实例的引用
  const layerControlRef = useRef<L.Control.Layers | null>(null);
  // 存储当前地图上已添加的航线图层组的引用，用于更精确的移除
  const currentFlightPathGroupRef = useRef<L.FeatureGroup | null>(null);
  // 起飞点标记的引用
  const takeoffMarkerRef = useRef<L.Marker | null>(null);
  const DBL_CLICK_DELAY = 250;
  // 定义机场坐标
  const AIRPORT_COORDS: L.LatLngTuple = [35.771865, 120.025036]; // [lat, lng]

  // Helper to ensure debugLayersRef.current is a valid L.LayerGroup
  // 使用 useCallback 避免不必要的重新创建函数
  const getOrCreateDebugLayerGroup = useCallback(() => {
    // 检查是否是 L.FeatureGroup 实例，而不是 L.LayerGroup
    if (
      !debugLayersRef.current ||
      !(debugLayersRef.current instanceof L.FeatureGroup)
    ) {
      debugLayersRef.current = new L.FeatureGroup(); // 创建 L.FeatureGroup
      if (mapRef.current && !mapRef.current.hasLayer(debugLayersRef.current)) {
        mapRef.current.addLayer(debugLayersRef.current);
      }
    }
    return debugLayersRef.current;
  }, []);

  // 初始化地图 (只运行一次)
  useEffect(() => {
    if (!mapRef.current) {
      const map = L.map("map", {
        center: AIRPORT_COORDS, // 设置为机场坐标
        zoom: 15,
        zoomControl: false,
      });
      mapRef.current = map;

      // 定义并存储底图图层实例
      osmLayerRef.current = L.tileLayer(
        "https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png",
        {
          maxZoom: 19,
          attribution:
            '&copy; <a href="http://www.openstreetmap.org/copyright">OpenStreetMap</a>',
        }
      );

      esriSatelliteLayerRef.current = L.tileLayer(
        "https://server.arcgisonline.com/ArcGIS/rest/services/World_Imagery/MapServer/tile/{z}/{y}/{x}",
        {
          attribution:
            "Tiles &copy; Esri &mdash; Source: Esri, i-cubed, USDA, USGS, AEX, GeoEye, Getmapping, Aerogrid, IGN, IGP, UPR-EGP, and the GIS User Community",
          maxZoom: 19,
        }
      );

      googleSatelliteLayerRef.current = L.tileLayer(
        "https://mt1.google.com/vt/lyrs=s&x={x}&y={y}&z={z}",
        {
          attribution: "&copy; Google",
          maxZoom: 20,
        }
      );

      // 将默认图层（道路图）添加到地图
      esriSatelliteLayerRef.current.addTo(map);
      activeBaseLayerRef.current = esriSatelliteLayerRef.current; // 初始化当前激活的底图

      // 创建图层控制器
      const baseMaps = {
        "道路图 (OSM)": osmLayerRef.current,
        "卫星图 (Esri)": esriSatelliteLayerRef.current,
        "卫星图 (Google 备用)": googleSatelliteLayerRef.current,
      };

      const control = L.control // 将 control 存储到 ref
        .layers(baseMaps, undefined, { position: "bottomright" })
        .addTo(map);
      layerControlRef.current = control; // 存储图层控制器实例

      // 监听底图切换事件，更新 activeBaseLayerRef
      map.on("baselayerchange", (e: L.LayersControlEvent) => {
        activeBaseLayerRef.current = e.layer as L.TileLayer;
      });

      L.control
        .zoom({
          position: "topright",
        })
        .addTo(map);

      const drawnItems = new L.FeatureGroup();
      map.addLayer(drawnItems);
      drawnItemsRef.current = drawnItems;

      // 在这里初始化 debugLayersRef.current 为 L.FeatureGroup
      debugLayersRef.current = new L.FeatureGroup();
      map.addLayer(debugLayersRef.current);

      return () => {
        const currentMap = mapRef.current;
        const currentDebugLayers = debugLayersRef.current; // 捕获当前引用进行清
        const currentLayerControl = layerControlRef.current; // 获取当前图层控制器引用
        const currentFlightPathGroup = currentFlightPathGroupRef.current; // 获取当前航线图层组引用
        const currentTakeoffMarker = takeoffMarkerRef.current; // 获取起飞点标记引用
        if (currentMap) {
          currentMap.off("click");
          currentMap.off("dblclick");
          currentMap.off("baselayerchange"); // 清理事件监听器
          currentMap.doubleClickZoom.enable();
          if (tempPolygonRef.current) {
            currentMap.removeLayer(tempPolygonRef.current);
            tempPolygonRef.current = null;
          }
          // 显式从地图中移除调试图层，然后将其引用置空
          if (currentDebugLayers && currentMap.hasLayer(currentDebugLayers)) {
            currentMap.removeLayer(currentDebugLayers);
          }
          // 显式从地图中移除航线图层组
          if (
            currentFlightPathGroup &&
            currentMap.hasLayer(currentFlightPathGroup)
          ) {
            currentMap.removeLayer(currentFlightPathGroup);
          }
          // 显式从地图中移除起飞点标记
          if (
            currentTakeoffMarker &&
            currentMap.hasLayer(currentTakeoffMarker)
          ) {
            currentMap.removeLayer(currentTakeoffMarker);
          }
          // 移除图层控制器
          if (currentLayerControl) {
            currentMap.removeControl(currentLayerControl);
          }
          console.log("开始清理整个地图");
          currentMap.remove(); // 移除整个地图实例
          mapRef.current = null;
          debugLayersRef.current = null; // 显式置空 ref
          layerControlRef.current = null; // 清理图层控制器引用
          currentFlightPathGroupRef.current = null; // 清理航线图层组引用
          takeoffMarkerRef.current = null; // 清理起飞点标记引用
          // 清理底图引用
          osmLayerRef.current = null;
          esriSatelliteLayerRef.current = null;
          googleSatelliteLayerRef.current = null;
          activeBaseLayerRef.current = null;
        }
      };
    }
  }, []);

  // 处理地图点击和双击事件 (保持不变)
  // 将事件处理函数定义为 useCallback，避免不必要的重新创建
  const handleMapClick = useCallback(
    (e: L.LeafletMouseEvent) => {
      const map = mapRef.current;
      if (!map) return;

      // 如果处于设置起飞点模式
      if (isSettingTakeoffPoint) {
        setTakeoffPoint(e.latlng);
        onSetTakeoffPointMode(false); // 设置完成后关闭起飞点设置模式
        return; // 阻止继续执行多边形绘制逻辑
      }

      if (!isDrawingEnabled || drawnPolygon) return;

      if (clickTimeoutRef.current) {
        clearTimeout(clickTimeoutRef.current);
        clickTimeoutRef.current = null;
        return;
      }

      clickTimeoutRef.current = setTimeout(() => {
        drawingPointsRef.current.push(e.latlng);

        if (map) {
          if (tempPolygonRef.current) {
            map.removeLayer(tempPolygonRef.current);
          }
          if (drawingPointsRef.current.length >= 1) {
            tempPolygonRef.current = L.polygon(drawingPointsRef.current, {
              color: "#007bff",
              fillOpacity: 0.2,
              dashArray: "5, 5",
            }).addTo(map);
          }
        }
        clickTimeoutRef.current = null;
      }, DBL_CLICK_DELAY);
    },
    [
      isDrawingEnabled,
      drawnPolygon,
      isSettingTakeoffPoint,
      setTakeoffPoint,
      onSetTakeoffPointMode,
    ]
  ); // 依赖 isDrawingEnabled 和 drawnPolygon

  const handleMapDblClick = useCallback(
    (e: L.LeafletMouseEvent) => {
      // 如果处于设置起飞点模式，双击不应触发多边形绘制
      if (isSettingTakeoffPoint) return;

      if (!isDrawingEnabled || drawnPolygon) return;

      e.originalEvent.preventDefault();
      e.originalEvent.stopPropagation();
      const map = mapRef.current;
      if (!map) return;

      map.doubleClickZoom.disable();

      if (clickTimeoutRef.current) {
        clearTimeout(clickTimeoutRef.current);
        clickTimeoutRef.current = null;
      }

      drawingPointsRef.current.push(e.latlng);

      if (drawingPointsRef.current.length >= 3) {
        if (tempPolygonRef.current) {
          map.removeLayer(tempPolygonRef.current);
          tempPolygonRef.current = null;
        }

        const newPolygon = L.polygon(drawingPointsRef.current, {
          color: "#007bff",
          fillOpacity: 0.2,
        });
        drawnItemsRef.current?.clearLayers();
        drawnItemsRef.current?.addLayer(newPolygon);

        onPolygonCreated(newPolygon);
        console.log("多边形绘制完成，通知父组件，新多边形:", newPolygon);

        drawingPointsRef.current = [];
      } else {
        alert("多边形至少需要3个顶点。");
        drawingPointsRef.current = [];
        if (tempPolygonRef.current) {
          map.removeLayer(tempPolygonRef.current);
          tempPolygonRef.current = null;
        }
      }

      setTimeout(() => {
        map.doubleClickZoom.enable();
      }, 50);
    },
    [isDrawingEnabled, drawnPolygon, onPolygonCreated, isSettingTakeoffPoint]
  ); // 依赖 isDrawingEnabled, drawnPolygon, onPolygonCreated

  // 绑定和解绑地图事件监听器
  useEffect(() => {
    const map = mapRef.current;
    if (!map) return;

    map.on("click", handleMapClick);
    map.on("dblclick", handleMapDblClick);

    return () => {
      map.off("click", handleMapClick);
      map.off("dblclick", handleMapDblClick);
      if (clickTimeoutRef.current) {
        clearTimeout(clickTimeoutRef.current);
        clickTimeoutRef.current = null;
      }
    };
  }, [mapRef.current, handleMapClick, handleMapDblClick]); // 依赖地图实例和事件处理函数

  // 当 drawnPolygon 状态改变时，更新 drawnItemsRef (保持不变)
  useEffect(() => {
    console.log("MapComponent: drawnPolygon 状态更新:", drawnPolygon);
    if (drawnItemsRef.current) {
      drawnItemsRef.current.clearLayers();
      if (drawnPolygon) {
        drawnItemsRef.current.addLayer(drawnPolygon);
        mapRef.current?.fitBounds(drawnPolygon.getBounds(), {
          padding: [50, 50],
        });
      }
    }
  }, [drawnPolygon]);

  // 当 flightPathLayer 状态改变时，更新地图上的航线
  useEffect(() => {
    const map = mapRef.current;
    if (!map) return;

    // 1. 移除之前添加到地图上的航线图层组
    if (
      currentFlightPathGroupRef.current &&
      map.hasLayer(currentFlightPathGroupRef.current)
    ) {
      map.removeLayer(currentFlightPathGroupRef.current);
      currentFlightPathGroupRef.current = null; // 清空引用
    }

    // 2. 如果有新的航线图层，则添加到地图并存储引用
    if (flightPathLayer) {
      map.addLayer(flightPathLayer);
      currentFlightPathGroupRef.current = flightPathLayer; // 存储新航线图层组的引用
      map.fitBounds(flightPathLayer.getBounds(), { padding: [50, 50] });
    }
    // 注意：这里不再需要手动处理底图，L.control.layers 会自动管理底图的显示状态。
    // 也不再需要 map.eachLayer 循环，因为我们现在直接管理 flightPathLayer 这个 FeatureGroup。
  }, [flightPathLayer]); // 依赖 flightPathLayer 变化

  // 绘制状态改变时，清除临时绘制 (保持不变)
  useEffect(() => {
    if (!isDrawingEnabled && tempPolygonRef.current) {
      mapRef.current?.removeLayer(tempPolygonRef.current);
      tempPolygonRef.current = null;
      drawingPointsRef.current = [];
    }
  }, [isDrawingEnabled]);

  // <-- 新增调试图层渲染逻辑
  useEffect(() => {
    const map = mapRef.current;
    const debugLayers = getOrCreateDebugLayerGroup(); // 使用辅助函数获取或创建调试图层组
    if (!map || !debugLayers) {
      console.warn("Map or debugLayers not available for debug rendering.");
      return;
    }

    debugLayers.clearLayers(); // 清除旧的调试图层

    if (showDebugLayers && debugData) {
      // 绘制 rotatedPolygonForScan (红色虚线)
      if (debugData.rotatedPolygonForScan) {
        L.geoJSON(debugData.rotatedPolygonForScan, {
          style: {
            color: "red",
            weight: 2,
            opacity: 0.7,
            fillOpacity: 0,
            dashArray: "5, 5",
          },
        }).addTo(debugLayers);
      }

      // 绘制 bufferedPolygonForScan (黄色实线)
      if (debugData.bufferedPolygonForScan) {
        L.geoJSON(debugData.bufferedPolygonForScan, {
          style: {
            color: "yellow",
            weight: 2,
            opacity: 0.7,
            fillOpacity: 0.1,
            fillColor: "yellow",
          },
        }).addTo(debugLayers);
      }

      // 绘制 scanLines (绿色虚线)
      debugData.scanLines.forEach((line) => {
        L.geoJSON(line, {
          style: {
            color: "green",
            weight: 1,
            opacity: 0.5,
            dashArray: "2, 2",
          },
        }).addTo(debugLayers);
      });

      // 绘制 midPoints (蓝色圆点)
      debugData.midPoints.forEach((p) => {
        L.circleMarker([p.geometry.coordinates[1], p.geometry.coordinates[0]], {
          radius: 4,
          color: "blue",
          fillColor: "#00f",
          fillOpacity: 0.8,
        })
          .addTo(debugLayers)
          .bindTooltip(
            `Mid: [${p.geometry.coordinates[0].toFixed(
              5
            )}, ${p.geometry.coordinates[1].toFixed(5)}]`,
            { permanent: false, direction: "auto" }
          );
      });

      // 绘制 midPointsInPolygon (亮绿色圆点)
      debugData.midPointsInPolygon.forEach((p) => {
        L.circleMarker([p.geometry.coordinates[1], p.geometry.coordinates[0]], {
          radius: 6,
          color: "lime",
          fillColor: "#0f0",
          fillOpacity: 1,
        })
          .addTo(debugLayers)
          .bindTooltip(
            `IN: [${p.geometry.coordinates[0].toFixed(
              5
            )}, ${p.geometry.coordinates[1].toFixed(5)}]`,
            { permanent: false, direction: "auto" }
          );
      });

      // 调整地图视角以包含所有调试图层
      // 增加对 bounds 的 isValid() 检查，防止空图层组导致错误
      if (debugLayers.getLayers().length > 0) {
        const bounds = debugLayers.getBounds();
        if (bounds && bounds.isValid()) {
          map.fitBounds(bounds, { padding: [50, 50] });
        } else {
          console.warn(
            "Debug layers bounds are invalid or empty after adding layers."
          );
        }
      }
    }
  }, [debugData, showDebugLayers, getOrCreateDebugLayerGroup]); // 依赖 debugData 和 getOrCreateDebugLayerGroup

  // 新增 EFFECT: 渲染和管理起飞点标记
  useEffect(() => {
    const map = mapRef.current;
    if (!map) return;

    // 自定义起飞点图标 (蓝色 'S' 标记)
    const takeoffIcon = L.divIcon({
      className: "custom-takeoff-icon",
      html: '<div class="flex items-center justify-center w-8 h-8 rounded-full bg-blue-600 text-white text-lg font-bold shadow-lg">S</div>',
      iconSize: [32, 32],
      iconAnchor: [16, 32], // 锚点在图标底部中心
    });

    if (takeoffPoint) {
      if (!takeoffMarkerRef.current) {
        // 创建新的标记
        takeoffMarkerRef.current = L.marker(takeoffPoint, {
          icon: takeoffIcon,
          draggable: true, // 允许拖拽
        }).addTo(map);

        // 监听拖拽结束事件
        takeoffMarkerRef.current.on("dragend", (e) => {
          const newLatLng = e.target.getLatLng();
          setTakeoffPoint(newLatLng); // 更新 App 状态中的起飞点
          console.log("MapComponent: Takeoff point dragged to:", newLatLng);
        });
      } else {
        // 更新现有标记的位置
        takeoffMarkerRef.current.setLatLng(takeoffPoint);
      }
    }
    // 清理函数：在组件卸载或 takeoffPoint 变为 null 时移除标记
    // 但现在 takeoffPoint 总是存在，所以只有组件卸载时才需要清理
    return () => {
      if (
        mapRef.current &&
        takeoffMarkerRef.current &&
        mapRef.current.hasLayer(takeoffMarkerRef.current)
      ) {
        mapRef.current.removeLayer(takeoffMarkerRef.current);
        takeoffMarkerRef.current = null;
      }
    };
  }, [takeoffPoint, setTakeoffPoint, mapRef.current]); // 依赖 takeoffPoint 和 map 实例

  return (
    <div id="map" className="flex-grow bg-[#333]">
      {isSettingTakeoffPoint && ( // 新增：设置起飞点模式的提示
        <div className="absolute top-4 left-1/2 -translate-x-1/2 bg-yellow-600 text-white text-sm px-3 py-1 rounded-md shadow-lg z-40">
          请在地图上**点击**设置起飞点。
        </div>
      )}
      {isDrawingEnabled && !drawnPolygon && (
        <div className="absolute top-4 left-1/2 -translate-x-1/2 bg-blue-600 text-white text-sm px-3 py-1 rounded-md shadow-lg z-40">
          请在地图上**点击**添加顶点，**双击**完成绘制。
        </div>
      )}
      {drawnPolygon && (
        <div className="absolute top-4 right-4 bg-[#2a2a2a] text-[#e0e0e0] text-sm px-3 py-1 rounded-md shadow-lg !z-[1000] flex space-x-2">
          <span>已绘制区域</span>
          <button
            className="text-[#007bff] hover:text-[#0056b3]"
            onClick={() => {
              drawnItemsRef.current?.clearLayers();
              onPolygonDeleted();
              debugLayersRef.current?.clearLayers(); // <-- 删除时清除调试图层
              console.log("删除按钮点击，通知父组件删除多边形");
            }}
          >
            删除
          </button>
        </div>
      )}
    </div>
  );
};

export default MapComponent;
